#include <grpcpp/grpcpp.h>

#include <iostream>
#include <memory>
#include <string>

#include "calculator.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;

class CalculatorClient {
public:
    CalculatorClient(std::shared_ptr<Channel> channel)
        : stub_(calculator::CalculatorService::NewStub(channel)) {}

    int Add(int a, int b) {
        calculator::AddRequest request;
        request.set_a(a);
        request.set_b(b);

        calculator::AddResponse response;
        ClientContext context;

        Status status = stub_->Add(&context, request, &response);

        if (status.ok()) {
            return response.result();
        } else {
            std::cout << "RPC failed" << std::endl;
            return -1;
        }
    }

    int Multiply(int a, int b) {
        calculator::MultiplyRequest request;
        request.set_a(a);
        request.set_b(b);

        calculator::MultiplyResponse response;
        ClientContext context;

        Status status = stub_->Multiply(&context, request, &response);

        if (status.ok()) {
            return response.result();
        } else {
            std::cout << "RPC failed" << std::endl;
            return -1;
        }
    }

private:
    std::unique_ptr<calculator::CalculatorService::Stub> stub_;
};

int main(int argc, char** argv) {
    std::string address("localhost:50051");
    CalculatorClient client(
            grpc::CreateChannel(address, grpc::InsecureChannelCredentials()));

    int a = 10, b = 20;
    int add_result = client.Add(a, b);
    std::cout << "Add Result: " << a << " + " << b << " = " << add_result << std::endl;

    int multiply_result = client.Multiply(a, b);
    std::cout << "Multiply Result: " << a << " * " << b << " = " << multiply_result << std::endl;

    return 0;
}
